package ycl.base.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import ycl.common.result.REnum;
import ycl.common.enums.FileTypeEnum;
import ycl.common.exception.CustomException;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

/**
 * 文件上传工具
 *
 * @author ycl
 * @date 2022/7/6 0006 15:11:38
 */
@Slf4j
public class UploadFileUtil {

	/**
	 * 文件上传前获取的参数
	 *
	 * @param userId     用户id
	 * @param file       多媒体文件
	 * @param type       文件类型
	 * @param pathPrefix 路径
	 * @return 文件上传时的参数
	 */
	public static UploadFileData getUploadData(
			Long userId,
			MultipartFile file,
			FileTypeEnum type,
			String pathPrefix) {
		//校验文件各项参数是否满足
		Assert.isFalse(file.isEmpty(), "请选择文件");
		String filename = file.getOriginalFilename();//获取文件名带后缀
		assert filename != null;
		String suffix = FileUtil.extName(filename);//获取文件后缀
		Assert.isTrue(ArrayUtil.containsIgnoreCase(type.types, suffix), "文件格式不支持");

		String userOutPath = pathPrefix + "/" + userId + "/" + suffix + "/";
		String publicOutPath = pathPrefix + "/public/" + suffix + "/";
		String uuid = IdUtil.fastSimpleUUID();
		String fileUuidName = uuid + "." + suffix;
		long fileSize = file.getSize();

		UploadFileData data = new UploadFileData();
		data.setUserId(userId)
				.setFileUuid(uuid)
				.setFileUuidName(fileUuidName)
				.setFilename(getFilename(userOutPath, filename, suffix))
				.setFileSize(fileSize)
				.setUserOutPath(userOutPath)
				.setSuffix(suffix)
				.setPublicOutPath(publicOutPath);
		try {
			String crypto = SecureUtil.md5(Arrays.toString(file.getBytes()));//转字节加密得到密文
			data.setCrypto(crypto);
		} catch (IOException e) {
			log.error("UploadFileUtil --- getUploadData --- file upload exception");
			log.error("{}", e.getMessage(), e);
			throw new CustomException(REnum.CUSTOM_FILE_UPLOAD_EXCEPTION);
		}
		return data;
	}


	/**
	 * 获取文件别名, 展示给用户的文件名
	 *
	 * @param path     路径
	 * @param filename 原文件名
	 * @param suffix   后缀
	 * @return 新文件名, 如果路径里没有这个文件, 那返回的文件名就是原文件名, 否则就会在后面+ -1
	 */
	private static String getFilename(String path, String filename, String suffix) {
		String name = filename.substring(0, filename.lastIndexOf("."));//获取文件名不带后缀
		File file = new File(path, filename);
		int index = 1;
		String res = filename;
		while (file.exists()) {
			res = name + "-" + index++ + "." + suffix;
			file = new File(path, res);
		}
		return res;
	}


	public static void uploadFile(MultipartFile file, String path, String filename) {
		File dir = new File(path);//目标目录
		dir.mkdirs();//创建目录
		String s1 = path + filename;//上传路径+文件名
		File target = new File(s1);//目标文件
		try {
			file.transferTo(target);
		} catch (IOException e) {
			log.error("UploadFileUtil ===> uploadFile ===> exception");
			log.error("{}", e.getMessage(), e);
			throw new CustomException(REnum.CUSTOM_FILE_UPLOAD_EXCEPTION);
		}
	}
}
